#include "ContactsServer.h"
#include "../common/ContactException.h"
#include "../common/httplib.h"

#define CONTACTS_HOST "127.0.0.1"
#define CONTACTS_PORT 8123

using namespace std;
using namespace httplib;
using namespace add_contact_req;


void ContactsServer::addContact()
{
    httplib::Client cli(CONTACTS_HOST, CONTACTS_PORT);
    
    // 1. 构建 req 
    add_contact_req::AddContactRequest req;
    buildAddContactRequest(&req);
    
    // 2. 序列化 req
    string req_str;
    if (!req.SerializeToString(&req_str)) {
        throw ContactException("序列化 AddContactRequest 失败");
    }

    // 3. 发起 POST 调用
    httplib::Result res = cli.Post("/contacts/add", req_str, "application/protobuf");

    // 网络层错误
    if (!res) {
        string err_desc;
        err_desc.append("/contacts/add 链接错误！");
        DEBUG_LOG(err_desc);  // 打印调试日志
        throw ContactException(err_desc);
    }

    // HTTP 状态码错误
    if (res->status != 200) {
        string err_desc;
        err_desc.append("/contacts/add 调用失败 ")
                .append(std::to_string(res->status))
                .append("(").append(res->reason).append(")");
        DEBUG_LOG(err_desc);  // 打印调试日志
        throw ContactException(err_desc);
    }

    // 4. 反序列化 resp 
    add_contact_resp::AddContactResponse resp;
    if (!resp.ParseFromString(res->body)) {
        string err_desc = "/contacts/add 响应反序列化失败!";
        DEBUG_LOG(err_desc);  // 打印调试日志
        throw ContactException(err_desc);
    }

    // 5. 业务逻辑结果
    if (resp.base_resp().success()) {
        cout << "✅ 添加联系人成功, UID = " << resp.uid() << endl;
    } else {
        string err_desc;
        err_desc.append("❌ 添加联系人失败, 原因: ")
                .append(resp.base_resp().error_desc());
        DEBUG_LOG(err_desc);   // 打印详细错误日志（带文件和行号）
        throw ContactException(err_desc);
    }

    
}


void ContactsServer::delContact()
{
    httplib::Client cli(CONTACTS_HOST, CONTACTS_PORT);

    // 1. 构造请求
    del_conctact_req::DelContactRequest req;

    cout << "请输入要删除的联系人 UID: ";
    string uid;
    getline(cin,uid);
    req.set_uid(uid);

    // 2. 序列化 req
    string req_str;
    if(!req.SerializeToString(&req_str))
    {
        DEBUG_LOG("序列化 DelContactRequest 失败");
    }

    // 3. 发起 POST 调用   
    httplib::Result res = cli.Post("/contacts/del", req_str, "application/protobuf");

    // 网络层错误
    if (!res) {
        string err_desc = "/contacts/del 链接错误！";
        DEBUG_LOG(err_desc);
        throw ContactException(err_desc);
    }

    // HTTP 状态码错误
    if (res->status != 200) {
        string err_desc;
        err_desc.append("/contacts/del 调用失败 ")
                .append(std::to_string(res->status))
                .append("(").append(res->reason).append(")");
        DEBUG_LOG(err_desc);
        throw ContactException(err_desc);
    }

    // 4. 反序列化 resp 
    del_contact_resp::BaseResponse resp;
    if(!resp.ParseFromString(res->body))
    {
        string err_desc = "/contacts/del 响应反序列化失败!";
        DEBUG_LOG(err_desc);
    }

    // 5. 业务逻辑结果
     if (resp.success()) {
        cout << "✅ 删除联系人成功" << endl;
    } else {
        string err_desc = "❌ 删除联系人失败: " + resp.error_desc();
        DEBUG_LOG(err_desc);
        throw ContactException(err_desc);
    }
}


void ContactsServer::findContacts()
{
    httplib::Client cli(CONTACTS_HOST, CONTACTS_PORT);

    // 1. 构造请求
    find_all_contact_req::FindAllContactRequest req;
    string req_str;
    
    // 2. 序列化 req
    if(!req.SerializeToString(&req_str))
    {
        DEBUG_LOG("序列化 findContact 失败");
    }
    
    // 3. 发起 POST 调用   
    auto res = cli.Post("/contacts/find-all",req_str,"application/protobuf");
    // 网络层错误
    if (!res) {
        string err_desc = "/contacts/find-one 链接错误！";
        DEBUG_LOG(err_desc);
        throw ContactException(err_desc);
    }

    // HTTP 状态码错误
    if (res->status != 200) {
        string err_desc;
        err_desc.append("/contacts/find-one 调用失败 ")
                .append(std::to_string(res->status))
                .append("(").append(res->reason).append(")");
        DEBUG_LOG(err_desc);
        throw ContactException(err_desc);
    }
    
    //4. 反序列化
    find_all_contact_resp::FindAllContactResponse  resp;
    if(!resp.ParseFromString(res->body))
    {
        string error = "查询失败 " + resp.base_resp().error_desc();
        DEBUG_LOG(error);
        return;
    }

     // 输出结果
    if (!resp.base_resp().success())
    {
        DEBUG_LOG("查询失败: " + resp.base_resp().error_desc());
        return;
    }

    std::cout << "===== 通讯录列表 =====" << std::endl;

    for(find_all_contact_resp::ContactInfo contact : resp.contacts())
    {
        std::cout << "姓名: " << contact.name() << std::endl;
        std::cout << "Uid: " << contact.uid() << std::endl;
        std::cout << "年龄: " << contact.age() << std::endl;
        std::cout << "电话: ";
        for(int i = 0; i < contact.phone_size(); i++)
        {
            std::cout << contact.phone(i);
            if (i < contact.phone_size() - 1)
                std::cout << ", ";
        }
        std::cout << std::endl;
        std::cout << "----------------------------------" << std::endl;
    }
       
}




void ContactsServer::findContact()
{
    httplib::Client cli(CONTACTS_HOST, CONTACTS_PORT);
    
    // 1. 构造请求
    find_one_contact_req::FindOneContactRequest req;
    cout << "请输入查找人的姓名: ";
    string name;
    getline(cin,name);
    req.set_name(name);

    string req_str;
    // 2. 序列化 req
    if(!req.SerializeToString(&req_str))
    {
        DEBUG_LOG("序列化 findContact 失败");
    }

    // 3. 发起 POST 调用   
    httplib::Result res = cli.Post("/contacts/find-one", req_str, "application/protobuf");

    // 网络层错误
    if (!res) {
        string err_desc = "/contacts/find-one 链接错误！";
        DEBUG_LOG(err_desc);
        throw ContactException(err_desc);
    }

    // HTTP 状态码错误
    if (res->status != 200) {
        string err_desc;
        err_desc.append("/contacts/find-one 调用失败 ")
                .append(std::to_string(res->status))
                .append("(").append(res->reason).append(")");
        DEBUG_LOG(err_desc);
        throw ContactException(err_desc);
    }

    //4. 反序列化
    find_one_contact_resp::FindOneContactResponse resp;
    if(!resp.ParseFromString(res->body))
    {
        DEBUG_LOG("/contacts/find-one 响应反序列化失败!");
    }

    //5. 处理逻辑
    if(resp.base_reso().success())
    {
        cout << "✅ 查找成功!" << endl;
        cout << "UID: " << resp.uid() << endl;
        cout << "姓名: " << resp.name() << endl;
        cout << "年龄: " << resp.age() << endl;
        cout << "电话: ";

        for(int i = 0; i < resp.phone_size(); i++)
        {
            cout << resp.phone(i);
            if (i < resp.phone_size() - 1) cout << ", ";
        }
        cout << endl;
    }
    else 
    {
        string err_desc;
        err_desc.append("❌ 查找失败, 原因: ")
                .append(resp.base_reso().error_desc());
        cout << err_desc << endl;
        DEBUG_LOG(err_desc);
    }
}


void ContactsServer::buildAddContactRequest(add_contact_req::AddContactRequest* req)
{
    cout << "请输入联系人姓名： ";
    string name;
    getline(cin,name);
    req->set_name(name);

    cout << "请输入联系人年龄:  ";
    int age;
    cin >> age;
    cin.ignore(256,'\n');
    req->set_age(age);
    

    while(true)
    {
        cout << "请输入联系人电话号码(输入回车结束):  ";
        string number;
        getline(cin,number);
        if(number.empty())
            break;
        
        AddContactRequest::Phone* phone = req->add_phone();
        phone->set_number(number);

        
        cout << "请输入联系人电话类型:\n"
             << "1. 移动电话\n"
             << "2. 固定电话\n"
             << "请选择: ";
             
        int choose;
        cin >> choose;
        cin.ignore(256, '\n');

    
        switch(choose)
        {
            case 1:
                phone->set_type(add_contact_req::AddContactRequest::Phone::MP);
                break;
            case 2:
                phone->set_type(add_contact_req::AddContactRequest::Phone::TEL);
                break;
            default :
                cout << "输入错误，默认设置为移动电话" << endl;
                phone->set_type(add_contact_req::AddContactRequest::Phone::MP);
                break;
        }
    }
}

// void printFindOneContactResponse(find_one_contact_resp::FindOneContactResponse& resp)
// {

// }
// void printFindAllContactsResponse(find_all_contacts_resp::FindAllContactsResponse& resp)
// {

// }